/**
 * JDBC URL 生成器
 * 支持多种数据库类型的JDBC连接字符串动态生成
 */

/**
 * 数据库类型配置
 */
const DB_CONFIG = {
  mysql: {
    name: 'MySQL',
    urlTemplate: 'jdbc:mysql://{host}:{port}/{database}',
    defaultParams: 'useUnicode=true&characterEncoding={charset}&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true',
    driver: 'com.mysql.cj.jdbc.Driver'
  },
  postgresql: {
    name: 'PostgreSQL',
    urlTemplate: 'jdbc:postgresql://{host}:{port}/{database}',
    defaultParams: 'currentSchema=public&characterEncoding={charset}',
    driver: 'org.postgresql.Driver'
  },
  sqlserver: {
    name: 'SQL Server',
    urlTemplate: 'jdbc:sqlserver://{host}:{port};DatabaseName={database}',
    defaultParams: 'encrypt=false&trustServerCertificate=true',
    driver: 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
  },
  oracle: {
    name: 'Oracle',
    // Oracle支持两种连接方式：SID和ServiceName
    urlTemplate: 'jdbc:oracle:thin:@{host}:{port}:{database}',
    urlTemplateServiceName: 'jdbc:oracle:thin:@//{host}:{port}/{database}',
    defaultParams: '',
    driver: 'oracle.jdbc.driver.OracleDriver'
  },
  dm: {
    name: '达梦数据库',
    urlTemplate: 'jdbc:dm://{host}:{port}/{database}',
    defaultParams: 'charset={charset}',
    driver: 'dm.jdbc.driver.DmDriver'
  },
  kingbase: {
    name: '人大金仓',
    urlTemplate: 'jdbc:kingbase8://{host}:{port}/{database}',
    defaultParams: 'currentSchema=public&characterEncoding={charset}',
    driver: 'com.kingbase8.Driver'
  },
  gbase: {
    name: '南大通用',
    urlTemplate: 'jdbc:gbase://{host}:{port}/{database}',
    defaultParams: 'characterEncoding={charset}',
    driver: 'com.gbase.jdbc.Driver'
  },
  mariadb: {
    name: 'MariaDB',
    urlTemplate: 'jdbc:mariadb://{host}:{port}/{database}',
    defaultParams: 'useUnicode=true&characterEncoding={charset}&useSSL=false&serverTimezone=Asia/Shanghai',
    driver: 'org.mariadb.jdbc.Driver'
  },
  db2: {
    name: 'DB2',
    urlTemplate: 'jdbc:db2://{host}:{port}/{database}',
    defaultParams: 'currentSchema=DB2ADMIN',
    driver: 'com.ibm.db2.jcc.DB2Driver'
  },
  clickhouse: {
    name: 'ClickHouse',
    urlTemplate: 'jdbc:clickhouse://{host}:{port}/{database}',
    defaultParams: 'socket_timeout=300000',
    driver: 'ru.yandex.clickhouse.ClickHouseDriver'
  }
}

/**
 * 生成JDBC连接字符串
 * @param {Object} config - 数据库配置
 * @param {string} config.dbType - 数据库类型
 * @param {string} config.host - 主机地址
 * @param {number} config.port - 端口
 * @param {string} config.database - 数据库名
 * @param {string} config.charset - 字符编码（可选，默认utf8）
 * @param {string} config.params - 额外参数（可选）
 * @param {boolean} config.useServiceName - Oracle是否使用ServiceName方式（可选）
 * @returns {string} JDBC连接字符串
 */
export function generateJdbcUrl(config) {
  const {
    dbType,
    host,
    port,
    database,
    charset = 'utf8',
    params = '',
    useServiceName = false
  } = config

  // 验证必填参数
  if (!dbType || !host || !database) {
    return ''
  }

  // 获取数据库配置
  const dbConfig = DB_CONFIG[dbType]
  if (!dbConfig) {
    console.error(`不支持的数据库类型: ${dbType}`)
    return ''
  }

  // 选择URL模板（Oracle特殊处理）
  let urlTemplate = dbConfig.urlTemplate
  if (dbType === 'oracle' && useServiceName) {
    urlTemplate = dbConfig.urlTemplateServiceName
  }

  // 替换模板变量
  let jdbcUrl = urlTemplate
    .replace('{host}', host)
    .replace('{port}', port || getDefaultPort(dbType))
    .replace('{database}', database)

  // 处理默认参数
  let defaultParams = dbConfig.defaultParams
  if (defaultParams) {
    defaultParams = defaultParams.replace('{charset}', charset)
  }

  // 合并参数
  const allParams = mergeParams(defaultParams, params)

  // 拼接参数
  if (allParams) {
    // SQL Server 使用分号分隔
    if (dbType === 'sqlserver') {
      jdbcUrl += ';' + allParams
    } else {
      jdbcUrl += '?' + allParams
    }
  }

  return jdbcUrl
}

/**
 * 合并参数字符串
 * @param {string} defaultParams - 默认参数
 * @param {string} customParams - 自定义参数
 * @returns {string} 合并后的参数字符串
 */
function mergeParams(defaultParams, customParams) {
  const params = {}

  // 解析默认参数
  if (defaultParams) {
    const pairs = defaultParams.split('&')
    pairs.forEach(pair => {
      const [key, value] = pair.split('=')
      if (key) {
        params[key.trim()] = value ? value.trim() : ''
      }
    })
  }

  // 解析自定义参数（会覆盖默认参数）
  if (customParams) {
    const pairs = customParams.split('&')
    pairs.forEach(pair => {
      const [key, value] = pair.split('=')
      if (key) {
        params[key.trim()] = value ? value.trim() : ''
      }
    })
  }

  // 拼接参数
  return Object.entries(params)
    .map(([key, value]) => value ? `${key}=${value}` : key)
    .join('&')
}

/**
 * 获取数据库默认端口
 * @param {string} dbType - 数据库类型
 * @returns {number} 默认端口
 */
export function getDefaultPort(dbType) {
  const portMap = {
    mysql: 3306,
    postgresql: 5432,
    sqlserver: 1433,
    oracle: 1521,
    dm: 5236,
    kingbase: 54321,
    gbase: 5258,
    mariadb: 3306,
    db2: 50000,
    clickhouse: 8123
  }
  return portMap[dbType] || 3306
}

/**
 * 获取数据库驱动类名
 * @param {string} dbType - 数据库类型
 * @returns {string} 驱动类名
 */
export function getDriverClassName(dbType) {
  const dbConfig = DB_CONFIG[dbType]
  return dbConfig ? dbConfig.driver : ''
}

/**
 * 解析JDBC URL
 * @param {string} jdbcUrl - JDBC连接字符串
 * @returns {Object} 解析结果
 */
export function parseJdbcUrl(jdbcUrl) {
  if (!jdbcUrl) {
    return null
  }

  // 基本格式：jdbc:<dbType>://<host>:<port>/<database>?<params>
  const result = {
    dbType: '',
    host: '',
    port: '',
    database: '',
    params: {}
  }

  try {
    // 提取数据库类型
    const dbTypeMatch = jdbcUrl.match(/jdbc:(\w+):/)
    if (dbTypeMatch) {
      result.dbType = dbTypeMatch[1]
    }

    // 根据不同数据库类型解析
    if (result.dbType === 'mysql' || result.dbType === 'mariadb' || 
        result.dbType === 'postgresql' || result.dbType === 'dm' || 
        result.dbType === 'kingbase' || result.dbType === 'gbase' ||
        result.dbType === 'clickhouse') {
      // 格式：jdbc:<dbType>://<host>:<port>/<database>?<params>
      const match = jdbcUrl.match(/\/\/([^:]+):(\d+)\/([^?]+)(\?(.+))?/)
      if (match) {
        result.host = match[1]
        result.port = parseInt(match[2])
        result.database = match[3]
        if (match[5]) {
          result.params = parseParams(match[5])
        }
      }
    } else if (result.dbType === 'sqlserver') {
      // 格式：jdbc:sqlserver://<host>:<port>;DatabaseName=<database>;<params>
      const match = jdbcUrl.match(/\/\/([^:]+):(\d+);(.+)/)
      if (match) {
        result.host = match[1]
        result.port = parseInt(match[2])
        const params = match[3].split(';')
        params.forEach(param => {
          const [key, value] = param.split('=')
          if (key === 'DatabaseName') {
            result.database = value
          } else if (key && value) {
            result.params[key] = value
          }
        })
      }
    } else if (result.dbType === 'oracle') {
      // 格式：jdbc:oracle:thin:@<host>:<port>:<sid> 或 jdbc:oracle:thin:@//<host>:<port>/<serviceName>
      if (jdbcUrl.includes('@//')) {
        // ServiceName方式
        const match = jdbcUrl.match(/@\/\/([^:]+):(\d+)\/(.+)/)
        if (match) {
          result.host = match[1]
          result.port = parseInt(match[2])
          result.database = match[3]
        }
      } else {
        // SID方式
        const match = jdbcUrl.match(/@([^:]+):(\d+):(.+)/)
        if (match) {
          result.host = match[1]
          result.port = parseInt(match[2])
          result.database = match[3]
        }
      }
    } else if (result.dbType === 'db2') {
      // 格式：jdbc:db2://<host>:<port>/<database>:<params>
      const match = jdbcUrl.match(/\/\/([^:]+):(\d+)\/([^:]+)(:(.+))?/)
      if (match) {
        result.host = match[1]
        result.port = parseInt(match[2])
        result.database = match[3]
        if (match[5]) {
          result.params = parseParams(match[5])
        }
      }
    }
  } catch (error) {
    console.error('解析JDBC URL失败:', error)
    return null
  }

  return result
}

/**
 * 解析参数字符串
 * @param {string} paramsStr - 参数字符串
 * @returns {Object} 参数对象
 */
function parseParams(paramsStr) {
  const params = {}
  const pairs = paramsStr.split('&')
  pairs.forEach(pair => {
    const [key, value] = pair.split('=')
    if (key) {
      params[key.trim()] = value ? decodeURIComponent(value.trim()) : ''
    }
  })
  return params
}

/**
 * 获取所有支持的数据库类型
 * @returns {Array} 数据库类型列表
 */
export function getSupportedDatabases() {
  return Object.entries(DB_CONFIG).map(([key, value]) => ({
    value: key,
    label: value.name,
    driver: value.driver
  }))
}

/**
 * 验证JDBC URL格式
 * @param {string} jdbcUrl - JDBC连接字符串
 * @returns {boolean} 是否有效
 */
export function validateJdbcUrl(jdbcUrl) {
  if (!jdbcUrl || typeof jdbcUrl !== 'string') {
    return false
  }
  
  // 基本格式检查
  if (!jdbcUrl.startsWith('jdbc:')) {
    return false
  }
  
  // 尝试解析
  const parsed = parseJdbcUrl(jdbcUrl)
  return parsed !== null && parsed.host && parsed.database
}

export default {
  generateJdbcUrl,
  parseJdbcUrl,
  getDefaultPort,
  getDriverClassName,
  getSupportedDatabases,
  validateJdbcUrl
}

